package com.umeox.watch.moto.camera.utils;


import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;

import com.umeox.moto.common.utils.AndroidUtils;
import com.umeox.moto.common.utils.FileUtils;
import com.umeox.moto.watch.themes.util.UToast;
import com.umeox.watch.moto.camera.CameraActivity;
import com.umeox.watch.moto.camera.R;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;

public class CameraUtils {

    public static final int QUALITY = 80;
    public static final Bitmap.CompressFormat FORMAT = Bitmap.CompressFormat.JPEG;


    public static File bitmapToFile(File dir, Bitmap bitmap, Context context) {

        FileOutputStream fos = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.compress(FORMAT, QUALITY, bos);
        final int size = bos.size();
        try {
            fos = new FileOutputStream(dir);
            fos.write(bos.toByteArray());
            fos.flush();

        } catch (Exception e) {
            if (size > AndroidUtils.getAvailableInternalMemory()) {
                UToast.showCustomToast(context, R.string.low_memory, Toast.LENGTH_LONG);
            }
            Log.e("Camera", "bitmapToFile: ", e);
            dir = null;
        } finally {
            FileUtils.closeIO(fos);
            if (!bitmap.isRecycled()) {
                bitmap.recycle();
            }
        }

        return dir;
    }

    public static void saveImageFile(byte[] data, Context context, boolean needRotate) {

        final BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inPreferredConfig = Bitmap.Config.RGB_565;
        Bitmap source = BitmapFactory.decodeByteArray(data, 0, data.length, opts);

        if (needRotate) {
            Matrix matrix = new Matrix();
            matrix.postScale(-1, 1);//水平镜像翻转
            source = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
        }

        String name = "IMG_" + System.currentTimeMillis() + "_" + AndroidUtils.getDeviceId() + ".jpg";
        String appGalleryCache = FileUtils.getAppGalleryCache();

        File file = new File(appGalleryCache, name);
        if (bitmapToFile(file, source, context) == null) {
            return;
        }

        saveToDataBase(context, file);
    }

    public static void saveFilterImageFile(byte[] data, Context context, int filterResId,boolean needRotate) {

        final BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inPreferredConfig = Bitmap.Config.RGB_565;
        Bitmap source = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
        Bitmap bitmapFg = BitmapFactory.decodeResource(context.getResources(), filterResId);

        if(needRotate){
            Matrix matrix = new Matrix();
            matrix.postScale(-1, 1);//水平镜像翻转
            source = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
        }

        Bitmap filterBitmap =  BitmapUtil.conver(240, 280, source);
        source = BitmapUtil.compositeBitmap(filterBitmap,bitmapFg);

        String name = "IMG_" + System.currentTimeMillis() + "_" + AndroidUtils.getDeviceId() + ".jpg";
        String appGalleryCache = FileUtils.getAppGalleryCache();

        File file = new File(appGalleryCache, name);
        if (bitmapToFile(file, source, context) == null) {
            return;
        }

        saveToDataBase(context, file);
    }

    /**
     * Save to system camera album
     *
     * @param context
     * @param file    FileName must be IMG_xxx_IMEI.jpg,@like{String name = "IMG_" + System.currentTimeMillis() + "_" + getDeviceId(context) + ".jpg";}
     */
    private static void saveToDataBase(Context context, File file) {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

        ContentValues galleryValues = new ContentValues();
        galleryValues.put("image_path", file.getAbsolutePath());
        galleryValues.put("image_server_path", "");
        galleryValues.put("image_name", file.getName());
        galleryValues.put("image_size", file.length());
        galleryValues.put("take_time", file.lastModified());
        context.getContentResolver().insert(CameraActivity.CONTENT_URI, galleryValues);
    }

    public static byte[] rotateYUVDegree90(byte[] data, int imageWidth, int imageHeight) {
        byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
        // Rotate the Y luma
        int i = 0;
        for (int x = 0; x < imageWidth; x++) {
            for (int y = imageHeight - 1; y >= 0; y--) {
                yuv[i] = data[y * imageWidth + x];
                i++;
            }
        }
        // Rotate the U and V color components
        i = imageWidth * imageHeight * 3 / 2 - 1;
        for (int x = imageWidth - 1; x > 0; x = x - 2) {
            for (int y = 0; y < imageHeight / 2; y++) {
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
                i--;
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
                i--;
            }
        }
        return yuv;
    }

    public static byte[] rotateYUVDegree270(byte[] data, int imageWidth, int imageHeight) {
        byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
        // Rotate the Y luma
        int i = 0;
        for (int x = imageWidth - 1; x >= 0; x--) {
            for (int y = 0; y < imageHeight; y++) {
                yuv[i] = data[y * imageWidth + x];
                i++;
            }
        }// Rotate the U and V color components
        i = imageWidth * imageHeight;
        for (int x = imageWidth - 1; x > 0; x = x - 2) {
            for (int y = 0; y < imageHeight / 2; y++) {
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
                i++;
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
                i++;
            }
        }
        return yuv;
    }

    public static byte[] rotateYUVDegree270AndMirror(byte[] data, int imageWidth, int imageHeight) {
        byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
        // Rotate and mirror the Y luma
        int i = 0;
        int maxY = 0;
        for (int x = imageWidth - 1; x >= 0; x--) {
            maxY = imageWidth * (imageHeight - 1) + x * 2;
            for (int y = 0; y < imageHeight; y++) {
                yuv[i] = data[maxY - (y * imageWidth + x)];
                i++;
            }
        }
        // Rotate and mirror the U and V color components
        int uvSize = imageWidth * imageHeight;
        i = uvSize;
        int maxUV = 0;
        for (int x = imageWidth - 1; x > 0; x = x - 2) {
            maxUV = imageWidth * (imageHeight / 2 - 1) + x * 2 + uvSize;
            for (int y = 0; y < imageHeight / 2; y++) {
                yuv[i] = data[maxUV - 2 - (y * imageWidth + x - 1)];
                i++;
                yuv[i] = data[maxUV - (y * imageWidth + x)];
                i++;
            }
        }
        return yuv;
    }

    private static Bitmap toHorizontalMirror(Bitmap bitmap){
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale(-1f,1f);
        return Bitmap.createBitmap(bitmap,0,0,w,h,matrix,true);
    }

}
